package ynu.edu.controller;

import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import io.github.resilience4j.retry.annotation.Retry;
import jakarta.annotation.Resource;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ynu.edu.entity.Cart;
import ynu.edu.entity.CommonResult;
import ynu.edu.entity.User;
import ynu.edu.feign.ServiceProviderService;
import ynu.edu.feign.UserDetailService;

import java.util.ArrayList;
import java.util.List;

/**
 * 购物车控制器
 * 提供购物车相关服务，集成断路器容错保护
 */
@RestController
@RequestMapping("/cart")
public class CartController {
    
    @Resource
    private ServiceProviderService serviceInstance; // 使用断路器A
    
    @Resource
    private UserDetailService userDetailService; // 使用断路器B

    /**
     * 获取购物车信息 - 使用断路器A保护
     * @param userId 用户ID
     * @return 购物车信息
     */
    @CircuitBreaker(name = "circuitA", fallbackMethod = "getCartByIdDown")
    @RateLimiter(name = "limiterForCart", fallbackMethod = "getCartByIdDown")
    @GetMapping("/getCartById/{userId}")
    @LoadBalanced
    public CommonResult<Cart> getCartById(@PathVariable("userId") Integer userId) {
        Cart cart = new Cart();
        List<String> goods = new ArrayList<>();
        goods.add("电池");
        goods.add("无人机");
        goods.add("笔记本电脑");
        cart.setGoodList(goods);
        User u = serviceInstance.GetUserById(userId);
        cart.setUser(u);

        Integer code = 200;
        String message = "success(16000) - 断路器A保护";

        CommonResult<Cart> commonResult = new CommonResult<>();
        commonResult.setCode(code);
        commonResult.setMessage(message);
        commonResult.setResult(cart);

        return commonResult;
    }

    /**
     * 获取用户详细信息 - 使用断路器B保护
     * @param userId 用户ID
     * @return 用户详细信息
     */
    @CircuitBreaker(name = "circuitB", fallbackMethod = "getUserDetailDown")
    @Bulkhead(name = "bulkheadForDetail", fallbackMethod = "getUserDetailDown")
    @GetMapping("/getUserDetail/{userId}")
    @LoadBalanced
    public CommonResult<User> getUserDetail(@PathVariable("userId") Integer userId) {
        User userDetail = userDetailService.getUserDetail(userId);

        Integer code = 200;
        String message = "success(16000) - 断路器B保护";

        CommonResult<User> commonResult = new CommonResult<>();
        commonResult.setCode(code);
        commonResult.setMessage(message);
        commonResult.setResult(userDetail);

        return commonResult;
    }

    /**
     * 购物车服务降级方法 - 断路器A触发
     * @param userId 用户ID
     * @param e 异常信息
     * @return 降级响应
     */
    public CommonResult<Cart> getCartByIdDown(Integer userId, Throwable e) {
        e.printStackTrace();
        String message = "断路器A或限流器触发 - 获取用户" + userId + "购物车信息的服务当前不可用，执行降级处理";
        System.out.println(message);
        
        // 创建降级购物车
        Cart fallbackCart = new Cart();
        List<String> fallbackGoods = new ArrayList<>();
        fallbackGoods.add("降级商品");
        fallbackCart.setGoodList(fallbackGoods);
        
        // 创建降级用户
        User fallbackUser = new User();
        fallbackUser.setUserId(userId);
        fallbackUser.setUserName("降级用户-" + userId);
        fallbackUser.setPassWord("服务暂时不可用");
        fallbackCart.setUser(fallbackUser);
        
        CommonResult<Cart> result = new CommonResult<>(400, message, fallbackCart);
        return result;
    }

    /**
     * 用户详细信息服务降级方法 - 断路器B触发
     * @param userId 用户ID
     * @param e 异常信息
     * @return 降级响应
     */
    public CommonResult<User> getUserDetailDown(Integer userId, Throwable e) {
        e.printStackTrace();
        String message = "断路器B或隔离器触发 - 获取用户" + userId + "详细信息的服务当前不可用，执行降级处理";
        System.out.println(message);
        
        // 创建降级用户详细信息
        User fallbackUser = new User();
        fallbackUser.setUserId(userId);
        fallbackUser.setUserName("详细降级用户-" + userId);
        fallbackUser.setPassWord("详细信息服务暂时不可用");
        
        CommonResult<User> result = new CommonResult<>(400, message, fallbackUser);
        return result;
    }
}
